﻿
using System;
using Castle.Core.Configuration;
using Castle.MicroKernel;
using Castle.Windsor;
using NHibernate.Cfg;

namespace Model.Common
{
    /// <summary>
    /// Ioc帮助类
    /// 程序启动时初始化IWindsorContainer对象，提供Ioc基本帮助方法
    /// </summary>
    public class IocHelper
    {
        /// <summary>
        /// 容器对象
        /// </summary>
        private static IWindsorContainer container;

        /// <summary>
        /// 返回内部使用的Ioc容器
        /// </summary>
        public static IWindsorContainer Container
        {
            get
            {
                if (container == null)
                {
                    throw new InvalidOperationException("Ioc容器没有被初始化");
                }

                return container;
            }
        }

        /// <summary>
        /// 容器是否已经初始化
        /// </summary>
        public static bool IsInitialized
        {
            get { return container != null; }
        }

        /// <summary>
        /// 初始化容器
        /// </summary>
        /// <param name="windsorContainer">容器对象</param>
        public static void Initialize(IWindsorContainer windsorContainer)
        {
            container = windsorContainer;
        }

        /// <summary>
        /// 分析并返回一个指定类型的服务
        /// </summary>
        /// <param name="serviceType">服务类型</param>
        /// <returns>服务对象</returns>
        public static object Resolve(Type serviceType)
        {
            return Container.Resolve(serviceType);
        }

        /// <summary>
        /// 通过制定类型和服务名称返回服务对象.
        /// </summary>
        /// <param name="serviceType">服务类型</param>
        /// <param name="serviceName">服务名称</param>
        /// <returns>服务对象</returns>
        public static object Resolve(Type serviceType, string serviceName)
        {
            return Container.Resolve(serviceName, serviceType);
        }

        /// <summary>
        /// 泛型返回指定类型的服务对象
        /// </summary>
        /// <typeparam name="T">泛型服务类型</typeparam>
        /// <returns>服务对象</returns>
        public static T Resolve<T>()
        {
            return Container.Resolve<T>();
        }

        /// <summary>
        /// 泛型返回指定类型和服务名称的服务对象
        /// </summary>
        /// <typeparam name="T">泛型服务类型</typeparam>
        /// <param name="name">服务名</param>
        /// <returns>服务对象</returns>
        public static T Resolve<T>(string name)
        {
            return Container.Resolve<T>(name);
        }

        /// <summary>
        /// 获取Castle的NhibernateFacility中配置的数据库连接字符串，为OracleHelper使用
        /// </summary>
        /// <param name="facilityID">设备Id</param>
        /// <param name="factoryID">连接数据库的FactoryID</param>
        /// <returns>连接串</returns>
        public static string GetConnectString(string facilityID, string factoryID)
        {
            IConfiguration facilityConfig = IocHelper.Container.Kernel.ConfigurationStore.GetFacilityConfiguration(facilityID);
            IConfiguration fesConfig = null;
            string constring = string.Empty;
            foreach (IConfiguration config in facilityConfig.Children)
            {
                if (config.Attributes["id"].ToLower() == factoryID.ToLower())
                    fesConfig = config;
            }

            IConfiguration settingConfig = fesConfig.Children["settings"];
            foreach (IConfiguration config in settingConfig.Children)
            {
                if (config.Attributes["key"].ToLower() == "connection.connection_string")
                    constring = config.Value;
            }

            return constring;
        }

        /// <summary>
        /// 获取NHibernate数据库配置类实例
        /// </summary>
        /// <param name="facilityID">设备ID</param>
        /// <param name="factoryAlias">数据库别名</param>
        /// <returns>返回找到的NHibernate配置类实例,找不到返回Null</returns>
        public static Configuration GetNHibernateCFG(string facilityID, string factoryAlias)
        {
            IConfiguration facilityConfig = IocHelper.Container.Kernel.ConfigurationStore.GetFacilityConfiguration(facilityID);
            string factoryID = string.Empty;
            if (string.IsNullOrEmpty(factoryAlias))
            {
                factoryAlias = "nh.facility.default";
            }
            foreach (IConfiguration config in facilityConfig.Children)
            {
                if (string.IsNullOrEmpty(config.Attributes["alias"]))
                {
                    config.Attributes["alias"] = "nh.facility.default";
                }

                if (config.Attributes["alias"].ToLower() == factoryAlias.ToLower())
                {
                    factoryID = config.Attributes["id"];
                    break;
                }
            }

            if (string.IsNullOrEmpty(factoryID))
            {
                return null;
            }

            string id = String.Format("{0}.cfg", factoryID);
            if (IocHelper.Container.Kernel.HasComponent(id))
            {
                return IocHelper.Container.Kernel.Resolve<Configuration>(id);
            }
            else
                return null;
        }
    }
}
